﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Strategy
{
    class Program
    {
        static void Main(string[] args)
        {
            //Context c1 = new Context(new ConcreteStrategyA());
            //c1.ContextInterface();
            //Console.WriteLine("c1 calle end");
            //Context c2 = new Context(new ConcreteStrategyB());
            //c2.ContextInterface();

            // Two contexts following different strategies
            SortList studentRecords = new SortList();
            studentRecords.Add("Sandra");
            studentRecords.Add("Vivek");
            studentRecords.Add("Anna");
            studentRecords.Add("Samual");
            studentRecords.Add("Jimmy");
            studentRecords.SetSortList(new QuickSort());
            studentRecords.Sort();
            Console.WriteLine();
            studentRecords.SetSortList(new ShellSort());
            studentRecords.Sort();

            Console.Read();
        }
    }

    abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }

    class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("AlgorithmInterface of {0} be called", this.GetType().Name);
        }
    }

    class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("AlgorithmInterface of {0} be called", this.GetType().Name);
        }
    }

    class Context
    {
        private Strategy _strategy;

        public Context(Strategy strategy)
        {
            this._strategy = strategy;
        }

        public void ContextInterface()
        {
            this._strategy.AlgorithmInterface();
        }
    }

    abstract class SortStrategy
    {
        public abstract void Sort(List<string> list);
    }

    class QuickSort : SortStrategy
    {
        public override void Sort(List<string> list)
        {
            list.Sort();
            Console.WriteLine("sort by {0} be used", this.GetType().Name);
        }
    }

    class ShellSort : SortStrategy
    {
        public override void Sort(List<string> list)
        {
            Console.WriteLine("sort by {0} be used", this.GetType().Name);
        }
    }

    class SortList
    {
        private List<string> _list = new List<string>();
        private SortStrategy _sortStrategy;

        public void SetSortList(SortStrategy sortStrategy)
        {
            this._sortStrategy = sortStrategy;
        }

        public void Add(string name)
        {
            this._list.Add(name);
        }

        public void Sort()
        {
            this._sortStrategy.Sort(_list);

            this._list.ForEach((item) => { Console.WriteLine(item); });
        }
    }
}
